﻿using System;
using System.Configuration;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using iPhotoUploader.Library;

namespace iPhotoUploader.GUI
{
    public partial class MainForm : Form
    {
        #region Protected Properties
        XmlDocument Xml = new XmlDocument();
        Album SelectedAlbum;
        List<Album> AllAlbums = new List<Album>();
        List<AlbumImage> AllImages = new List<AlbumImage>();
        List<AlbumFace> AllFaces = new List<AlbumFace>();
        List<YouTubeVideo> AllVideos = new List<YouTubeVideo>();
        string SuccessMessage = "OK";
        string MissingEventMessage = "Please select an event first!";
        string SelectedLibrary = "MacXmlPathLocal";
        activeexposure.iPhoto active = new activeexposure.iPhoto();
        #endregion

        #region Form Specific Methods
        public MainForm()
        {
            InitializeComponent();
        }

        public void SetLabel(string value)
        {
            lblEventName.Text = value;
            btnEditEvent.Enabled = true;
        }

        protected void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                string albumPath = GetAlbumPath();
                Xml.Load(albumPath);

                ReconcilePeople();

                AllImages = new List<AlbumImage>();
                AllImages = AlbumImage.LoadAllImages(Xml);

                LoadAlbums();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + " " + ex.InnerException);
            }
        }

        protected void lvAlbums_Click(object sender, EventArgs e)
        {
            ShowMessageBox("Loading images...");

            lvAlbum.Clear();
            var firstSelectedItem = lvAlbums.SelectedItems[0];

            var il = new ImageList { ImageSize = new Size(256, 256), ColorDepth = ColorDepth.Depth32Bit };
            lvAlbum.View = View.LargeIcon;
            lvAlbum.LargeImageList = il;

            SelectedAlbum = AllAlbums.Where(item => item.Name == firstSelectedItem.Text).FirstOrDefault();

            foreach (var image in SelectedAlbum.Images.Where(i => !i.IsVideo))
            {
                var isSelected = image.Id == SelectedAlbum.ListingImage.Id || image.IsWeb;
                
                il.Images.Add(image.Id, Image.FromFile(image.ThumbPath));

                lvAlbum.Items.Add(new ListViewItem { Text = image.Caption + " \n\r " + image.Name, ImageKey = image.Id, Checked = isSelected });   
            }
            SelectedAlbum.StartDate = (from d in SelectedAlbum.Images select d.Date).Min();
            SelectedAlbum.EndDate = (from d in SelectedAlbum.Images select d.Date).Max();

            ClearMessageBox();
        }

        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            ShowMessageBox("Uploading images...");
            
            if (!string.IsNullOrEmpty(Settings.EventId))
            {
                #region Submit Photos
                foreach (ListViewItem picture in lvAlbum.CheckedItems)
                {
                    try
                    {
                        var imageId = picture.ImageKey;
                        var image = (AlbumImage)AllImages.Where(item => item.Id == imageId).FirstOrDefault();
                        var caption = image.Caption;
                        var fileName = image.Name + ".jpg";
                        var imagePath = string.Empty;
                        var isListingPhoto = false;
                        if (image.Id == SelectedAlbum.ListingImage.Id)
                            isListingPhoto = true;

                        imagePath = image.ImagePath;

                        Byte[] img = ImageUtility.ResizeNew(imagePath, fileName, 583);

                        List<Guid> peopleIds = new List<Guid>();
                        foreach (int faceId in image.FaceIds)
                        {
                            AlbumFace face = AllFaces.Where(f => f.Id == faceId).FirstOrDefault();
                            if(face != null)
                                peopleIds.Add(face.PeopleId);
                        }

                        string successMessage = active.CreatePicture(img, fileName, caption, Settings.EventId, isListingPhoto, peopleIds.ToArray(), image.IsFavorite, image.Rating, image.Latitude, image.Longitude);

                        if (successMessage != SuccessMessage)
                            MessageBox.Show(successMessage);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                #endregion

                foreach (ListViewItem video in lvVideos.CheckedItems)
                {
                    try
                    {
                        var videoId = video.ImageKey;
                        var videoItem = (YouTubeVideo)AllVideos.Where(item => item.VideoId == videoId).FirstOrDefault();

                        string successMessage = active.CreateVideo(Settings.EventId, videoItem.VideoUrl, videoItem.Title, videoItem.Duration);

                        if (successMessage != SuccessMessage)
                            MessageBox.Show(successMessage);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                ClearMessageBox();
                MessageBox.Show("Complete!");
            }
            else
                MessageBox.Show(MissingEventMessage);
            
            
            ClearMessageBox();
        }

        protected void selectCategoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SelectEventForm form = new SelectEventForm();
            form.ShowDialog();
        }

        protected void addCategoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateEventForm form = new CreateEventForm();
            if (SelectedAlbum != null)
            {
                form.Edit = false;
                form.EventName = SelectedAlbum.Name;
                form.StartDate = SelectedAlbum.StartDate;
                form.EndDate = SelectedAlbum.EndDate;
            }
            form.ShowDialog();
        }

        protected void lvAlbum_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(Settings.EventId))
                MessageBox.Show(MissingEventMessage);
        }
        #endregion

        protected void ReconcilePeople()
        {
            AllFaces = new List<AlbumFace>();
            AllFaces = AlbumFace.LoadAllFaces(Xml);

            ShowMessageBox("Loading & Reconciling Faces with database...");

            List<activeexposure.PeopleLight> serverPeople = active.GetAllPeople().ToList();

            foreach (var face in AllFaces)
            {
                activeexposure.PeopleLight person = serverPeople.Where(p => p.FirstName == face.FirstName && p.LastName == face.LastName).FirstOrDefault();

                if (person != null)
                {
                    face.PeopleId = person.PeopleId;
                }
                else
                {
                    face.PeopleId = active.AddPeople(Guid.Empty, face.FirstName, face.LastName);
                }
            }

            ClearMessageBox();
        }

        protected void LoadAlbums()
        {
            try
            {
                AllAlbums = new List<Album>();
                AllAlbums = Album.LoadAllAlbums(Xml, AllImages);

                lvAlbum.Clear();
                lvAlbums.Items.Clear();
                var il = new ImageList { ImageSize = new Size(128, 128), ColorDepth = ColorDepth.Depth32Bit };
                lvAlbums.View = View.LargeIcon;
                lvAlbums.LargeImageList = il;

                foreach (Album album in AllAlbums)
                {
                    il.Images.Add(album.ListingImage.Id, Image.FromFile(album.ListingImage.ThumbPath));
                    lvAlbums.Items.Add(new ListViewItem { Text = album.Name, Name = "", ImageKey = album.ListingImage.Id });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        protected string GetAlbumPath()
        {
            string albumPath = Utility.CheckOSPath(ConfigurationManager.AppSettings[SelectedLibrary]);
            return Path.Combine(albumPath, "AlbumData.xml"); ;
        }

        protected void useLocalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SwitchLibrary(sender, e, "Local", "MacXmlPathLocal", true, false, false);
        }

        protected void useArchiveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SwitchLibrary(sender, e, "Archive", "MacXmlPathArchive", false, true, false);
        }

        private void useRyanArchiveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SwitchLibrary(sender, e, "Ryan Archive", "MacXmlPathRyanArchive", false, false, true);
        }

        protected void SwitchLibrary(object sender, EventArgs e, string libraryName, string libraryKeyName, bool useLocal, bool useArchive, bool useRyan)
        {
            ShowMessageBox("Switching libraries to " + libraryName + "...");

            useLocalToolStripMenuItem.Checked = useLocal;
            useArchiveToolStripMenuItem.Checked = useArchive;
            useRyanArchiveToolStripMenuItem.Checked = useRyan;
            SelectedLibrary = libraryKeyName;
            Form1_Load(sender, e);

            ClearMessageBox();
        }

        protected void ShowMessageBox(string message)
        {
            lblStatus.Text = message;
            lblStatus.Refresh();
        }

        protected void ClearMessageBox()
        {
            lblStatus.Text = string.Empty;
        }

        protected void LoadVideos()
        {
            try
            {
                ShowMessageBox("Loading videos...");

                if (AllVideos.Count == 0)
                {
                    lvVideos.Clear();

                    var il = new ImageList { ImageSize = new Size(256, 256), ColorDepth = ColorDepth.Depth32Bit };
                    lvVideos.View = View.LargeIcon;
                    lvVideos.LargeImageList = il;
                    Youtube youtube = new Youtube();
                    AllVideos = youtube.GetUploadedVideos();

                    foreach (YouTubeVideo video in AllVideos)
                    {
                        il.Images.Add(video.VideoId, video.ThumbNailImage);

                        lvVideos.Items.Add(new ListViewItem { Text = video.Title, ImageKey = video.VideoId });
                    }
                }
                ClearMessageBox();
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        protected void LoadExistingPhotos()
        {
            if (string.IsNullOrEmpty(Settings.EventId))
            {
                MessageBox.Show(MissingEventMessage);
            }
            else
            {
                lvExisting.Items.Clear();
                
                activeexposure.EventLight evt = active.GetEventByID(new Guid(Settings.EventId));
                var il = new ImageList { ImageSize = new Size(256, 256), ColorDepth = ColorDepth.Depth32Bit };
                lvExisting.View = View.LargeIcon;
                lvExisting.LargeImageList = il;

                foreach (activeexposure.PictureLight pic in evt.Pictures)
                {
                    Image img = LoadImage(pic.ImagePath);

                    if (img != null)
                        il.Images.Add(pic.Id.ToString(), img);
                    
                    lvExisting.Items.Add(new ListViewItem { Text = pic.Caption, Name = "", ImageKey = pic.Id.ToString() });
                }
            }
        }

        private Image LoadImage(string url)
        {
            try
            {
                string imagePrefix = ConfigurationManager.AppSettings["ImagePrefix"];
                WebRequest request = WebRequest.Create(imagePrefix + url);

                WebResponse response = request.GetResponse();
                Stream responseStream = response.GetResponseStream();

                Bitmap bmp = new Bitmap(responseStream);

                responseStream.Dispose();

                return bmp;
            }
            catch
            {

            }
            return null;
        }

        protected void tabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControl.SelectedTab.Name == "tabVideos")
            {
                LoadVideos();
            }
            else if (tabControl.SelectedTab.Name == "tabExistingPhotos")
            {
                LoadExistingPhotos();
            }
        }

        private void btnSelectAll_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lvAlbum.Items)
            {
                item.Checked = true;
            }
        }

        private void btnUnSelectAll_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lvAlbum.Items)
            {
                item.Checked = false;
            }
        }

        private void btnEditEvent_Click(object sender, EventArgs e)
        {
            CreateEventForm form = new CreateEventForm();
            if (Settings.EventId != null)
            {
                form.Edit = true;
            }
            form.ShowDialog();
        }

        private void lvExisting_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                ListViewItem item = lvExisting.GetItemAt(e.X, e.Y);

                if (item != null)
                {
                    contextMenuStrip1.Show(lvExisting, e.Location);
                }
            }
        }

        private void deletePhoto_Click(object sender, EventArgs e)
        {
            if (lvExisting.SelectedItems.Count > 0)
            {
                foreach (ListViewItem item in lvExisting.SelectedItems)
                    active.DeletePhoto(new Guid(item.ImageKey));

                LoadExistingPhotos();
            }
        }
    }
}
